/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef FMMU_IP_H
#define FMMU_IP_H

#include "lld_platform.h"
#include "regs_base.h"

#define FMMU_MAX_NUM            10
#define FMMU_SRC_RANGE_NUM      7
#define FMMU_DST_RANGE_NUM      4

#define FMMU_R52P_FLASH_REGION_MAX_NUM          32
#define FMMU_R52P_MASTER_REGION_MAX_NUM         16
#define FMMU_R5_REGION_MAX_NUM                  8

#define FMMU_REGION_NUM_MAX                     (FMMU_R52P_FLASH_REGION_MAX_NUM + FMMU_R52P_MASTER_REGION_MAX_NUM)


#define FMMU_ROM_START                          0x0ul
#define FMMU_ROM_END                            0x007FFFFFul
#define FMMU_FLASH_START                        0x08000000ul
#define FMMU_FLASH_END                          0x0FFFFFFFul
#define FMMU_R52P_LLPP_START                    0xF8000000ul
#define FMMU_R52P_LLPP_END                      0xFFFFFFFFul
#define FMMU_SE_LLPP_START                      0xF2000000ul
#define FMMU_SE_LLPP_END                        0xF32FFFFFul
#define FMMU_LP_LLPP_START                      0xF0000000ul
#define FMMU_LP_LLPP_END                        0xF10FFFFFul

#define FMMU_R52P_FLASH_SRCADDR_START           FMMU_FLASH_START
#define FMMU_R52P_FLASH_SRCADDR_END             FMMU_FLASH_END

#define FMMU_R52P_MASTER_SRCADDR_START1         FMMU_ROM_END + 1
#define FMMU_R52P_MASTER_SRCADDR_END1           FMMU_FLASH_START - 1
#define FMMU_R52P_MASTER_SRCADDR_START2         FMMU_FLASH_END + 1
#define FMMU_R52P_MASTER_SRCADDR_END2           FMMU_R52P_LLPP_START - 1

#define FMMU_SE_SRCADDR_START1                  FMMU_ROM_END + 1
#define FMMU_SE_SRCADDR_END1                    FMMU_SE_LLPP_START - 1
#define FMMU_SE_SRCADDR_START2                  FMMU_SE_LLPP_END + 1
#define FMMU_SE_SRCADDR_END2                    0xFFFFFFFFul

#define FMMU_LP_SRCADDR_START1                  FMMU_ROM_END + 1
#define FMMU_LP_SRCADDR_END1                    FMMU_LP_LLPP_START - 1
#define FMMU_LP_SRCADDR_START2                  FMMU_LP_LLPP_END + 1
#define FMMU_LP_SRCADDR_END2                    0xFFFFFFFFul

#define FMMU_DSTADDR_START                      FMMU_ROM_END +1
#define FMMU_DSTADDR_END                        0xFFFFFFFFul

typedef enum {
    FMMU_CORE_R52P0 = 0U,
    FMMU_CORE_R52P1,
    FMMU_CORE_R52P2,
    FMMU_CORE_R52P3,
    FMMU_CORE_SE,
    FMMU_CORE_LP,
    FMMU_CORE_MAX
} Fmmu_Core_t;

typedef enum {
    FMMU_TYPE_MASTER = 0U,
    FMMU_TYPE_FLASH,
    FMMU_TYPE_SE,
    FMMU_TYPE_LP,
    FMMU_TYPE_MAX
} Fmmu_Type_t;

typedef enum {
    FMMU_NO_MON = 0U,
    FMMU_HAVE_MON
} Fmmu_Monitor_t;

typedef struct
{
    Fmmu_Core_t core;
    Fmmu_Type_t fmmuType;
    Fmmu_Monitor_t monitor;
    uint8_t regionNum;
    uint32_t base;
} Fmmu_AttributeType;

typedef struct
{
    Fmmu_Type_t fmmuType;
    uint32_t startAddr;
    uint32_t endAddr;
} Fmmu_AddrRangeType;

#ifdef CFG_PLATFORM_MCAL
#define FMMU_START_SEC_CONST_UNSPECIFIED
#include "Fmmu_MemMap.h"
#endif /* #ifdef CFG_PLATFORM_MCAL */
const static Fmmu_AttributeType Fmmu_AttributeTable[FMMU_MAX_NUM] =
{
    {FMMU_CORE_R52P0,   FMMU_TYPE_FLASH,    FMMU_HAVE_MON,  FMMU_R52P_FLASH_REGION_MAX_NUM,     APB_R52P_F0_FMMU_BASE   },
    {FMMU_CORE_R52P1,   FMMU_TYPE_FLASH,    FMMU_HAVE_MON,  FMMU_R52P_FLASH_REGION_MAX_NUM,     APB_R52P_F1_FMMU_BASE   },
    {FMMU_CORE_R52P2,   FMMU_TYPE_FLASH,    FMMU_HAVE_MON,  FMMU_R52P_FLASH_REGION_MAX_NUM,     APB_R52P_F2_FMMU_BASE   },
    {FMMU_CORE_R52P3,   FMMU_TYPE_FLASH,    FMMU_HAVE_MON,  FMMU_R52P_FLASH_REGION_MAX_NUM,     APB_R52P_F3_FMMU_BASE   },
    {FMMU_CORE_R52P0,   FMMU_TYPE_MASTER,   FMMU_HAVE_MON,  FMMU_R52P_MASTER_REGION_MAX_NUM,    APB_R52P_M0_FMMU_BASE   },
    {FMMU_CORE_R52P1,   FMMU_TYPE_MASTER,   FMMU_HAVE_MON,  FMMU_R52P_MASTER_REGION_MAX_NUM,    APB_R52P_M1_FMMU_BASE   },
    {FMMU_CORE_R52P2,   FMMU_TYPE_MASTER,   FMMU_HAVE_MON,  FMMU_R52P_MASTER_REGION_MAX_NUM,    APB_R52P_M2_FMMU_BASE   },
    {FMMU_CORE_R52P3,   FMMU_TYPE_MASTER,   FMMU_HAVE_MON,  FMMU_R52P_MASTER_REGION_MAX_NUM,    APB_R52P_M3_FMMU_BASE   },
    {FMMU_CORE_SE,      FMMU_TYPE_SE,       FMMU_NO_MON,    FMMU_R5_REGION_MAX_NUM,             APB_R5_SE_FMMU_BASE     },
    {FMMU_CORE_LP,      FMMU_TYPE_LP,       FMMU_HAVE_MON,  FMMU_R5_REGION_MAX_NUM,             APB_FMMU_LP_BASE        },
};

const static Fmmu_AddrRangeType Fmmu_SrcAddrRangeTable[FMMU_SRC_RANGE_NUM] =
{
    {FMMU_TYPE_FLASH,   FMMU_R52P_FLASH_SRCADDR_START,      FMMU_R52P_FLASH_SRCADDR_END     },
    {FMMU_TYPE_MASTER,  FMMU_R52P_MASTER_SRCADDR_START1,    FMMU_R52P_MASTER_SRCADDR_END1   },
    {FMMU_TYPE_MASTER,  FMMU_R52P_MASTER_SRCADDR_START2,    FMMU_R52P_MASTER_SRCADDR_END2   },
    {FMMU_TYPE_SE,      FMMU_SE_SRCADDR_START1,             FMMU_SE_SRCADDR_END1            },
    {FMMU_TYPE_SE,      FMMU_SE_SRCADDR_START2,             FMMU_SE_SRCADDR_END2            },
    {FMMU_TYPE_LP,      FMMU_LP_SRCADDR_START1,             FMMU_LP_SRCADDR_END1            },
    {FMMU_TYPE_LP,      FMMU_LP_SRCADDR_START2,             FMMU_LP_SRCADDR_END2            },
};

const static Fmmu_AddrRangeType Fmmu_DstAddrRangeTable[FMMU_DST_RANGE_NUM] =
{
    {FMMU_TYPE_FLASH,   FMMU_DSTADDR_START, FMMU_DSTADDR_END    },
    {FMMU_TYPE_MASTER,  FMMU_DSTADDR_START, FMMU_DSTADDR_END    },
    {FMMU_TYPE_SE,      FMMU_DSTADDR_START, FMMU_DSTADDR_END    },
    {FMMU_TYPE_LP,      FMMU_DSTADDR_START, FMMU_DSTADDR_END    },
};
#ifdef CFG_PLATFORM_MCAL
#define FMMU_STOP_SEC_CONST_UNSPECIFIED
#include "Fmmu_MemMap.h"
#endif /* #ifdef CFG_PLATFORM_MCAL */
#endif /* FMMU_IP_H */

